import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.ArrayList;

public class SHA1 {
	/*
	 * Bitwise rotate a 32-bit number to the left
	 */
	private static int rol(int num, int cnt) {
		return (num << cnt) | (num >>> (32 - cnt));
	}

	/*
	 * Take a string and return the base64 representation of its SHA-1.
	 */
	public static String encode(byte[] x) {

		// Convert a string to a sequence of 16-word blocks, stored as an array.
		// Append padding bits and the length, as described in the SHA1 standard

		
//		byte[] x = str.getBytes();
		
		
		int[] blocks = new int[(((x.length + 8) >> 6) + 1) * 16];
		int i;

		for (i = 0; i < x.length; i++) {
			blocks[i >> 2] |= x[i] << (24 - (i % 4) * 8);
//			System.out.println((i >> 2) + " : " + (24 - (i % 4) * 8));
			System.out.println((i >> 2) + ": " + Integer.toHexString(blocks[i >> 2]));
		}

		blocks[i >> 2] |= 0x80 << (24 - (i % 4) * 8);
		System.out.println((i >> 2) + ": " + Integer.toHexString(blocks[i >> 2]));
		
		blocks[blocks.length - 1] = x.length * 8 + 0x400;
//		blocks[blocks.length - 1] = 0x8e8;
		System.out.println(blocks.length - 1 + ": " + Integer.toHexString(blocks[blocks.length - 1]));
		

		
//		for(int j = 0; j < blocks.length; j++)
//			System.out.println(blocks[j] + ".");
		// calculate 160 bit SHA1 hash of the sequence of blocks

		int[] w = new int[80];

//		int a =  1732584193;
//		int b = -271733879;
//		int c = -1732584194;
//		int d =  271733878;
//		int e = -1009589776;

//		int a = 0x67452301;
//		int b = 0xEFCDAB89;
//		int c = 0x98BADCFE;
//		int d = 0x10325476;
//		int e = 0xC3D2E1F0;

		int a = 0xf4b645e8;
		int b = 0x9faaec2f;
		int c = 0xf8e443c5;
		int d = 0x95009c16;
		int e = 0xdbdfba4b;
		
		for (i = 0; i < blocks.length; i += 16) {
			int olda = a;
			int oldb = b;
			int oldc = c;
			int oldd = d;
			int olde = e;

			for (int j = 0; j < 80; j++) {
				w[j] = (j < 16) ? blocks[i + j] : (rol(w[j - 3] ^ w[j - 8]
						^ w[j - 14] ^ w[j - 16], 1));

				int t = rol(a, 5)
						+ e
						+ w[j]
						+ ((j < 20) ? 1518500249 + ((b & c) | ((~b) & d))
								: (j < 40) ? 1859775393 + (b ^ c ^ d)
										: (j < 60) ? -1894007588
												+ ((b & c) | (b & d) | (c & d))
												: -899497514 + (b ^ c ^ d));
				e = d;
				d = c;
				c = rol(b, 30);
				b = a;
				a = t;
			}

			a = a + olda;
			b = b + oldb;
			c = c + oldc;
			d = d + oldd;
			e = e + olde;
		}

		// Convert 160 bit hash to base 16
		return new String(Integer.toHexString(a) + Integer.toHexString(b) + Integer.toHexString(c) + Integer.toHexString(d) + Integer.toHexString(e));
	}
	
	public static void main(String[] args) throws UnsupportedEncodingException {
		String original_message = "No one has completed lab 2 so give them all a 0";
		System.out.println(Integer.toHexString(original_message.length()*8 + 128));
		System.out.println(new BigInteger(original_message.getBytes("iso-8859-1")).toString(16));
		
//		String hack_message = "ffffffffffffffffNo one has completed lab 2 so give them all a 0x\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0unless you suspect impending nuclear war, in which case, we should be generous and allow everyone to pass. Maybe you should give everyone a 100 just in case.";
//		System.out.println(Integer.toHexString(hack_message.length()*8));
		
		String new_message = "unless you suspect impending nuclear war, in which case, we should be generous and allow everyone to pass. Maybe you should give everyone a 100 just in case.";
		System.out.println(new BigInteger(new_message.getBytes("iso-8859-1")).toString(16));
		//a1fd5703348583b9835f863f23726186354ba8f5
		
		
//		System.out.println(Integer.toHexString(original_message.length()*8));
		System.out.println(encode(original_message.getBytes()));
//		System.out.println(encode(new_message.getBytes()));
		
	}
}
